Skip to content

feat(release): v8.4.0 — decision request context + pasal_56b_dpa transfer basis#210

Merged
saurabhjain1592 merged 1 commit into
mainfrom
buku-e/sdk-v8.5.0
May 30, 2026
Merged

feat(release): v8.4.0 — decision request context + pasal_56b_dpa transfer basis#210
saurabhjain1592 merged 1 commit into
mainfrom
buku-e/sdk-v8.5.0

Conversation

@saurabhjain1592
Copy link
Copy Markdown
Member

@saurabhjain1592 saurabhjain1592 commented May 29, 2026

Summary

Multi-SDK v8.4.0 release (epic getaxonflow/axonflow-enterprise#2508) — Python SDK.

  1. Request context on decision reads (platform #2509). DecisionSummary and DecisionExplanation gain context: dict[str, str] | None; DecisionExplanation also gains context_truncated: bool | None. Pydantic resolves both via model_validate (the models already extra='ignore'/lenient, so no parser change). list_decisions() returns the platform-truncated 5-key summary; explain_decision() returns the full map.
  2. pasal_56b_dpa transfer basis (platform #2513). New TransferBasis Literal alias + TRANSFER_BASIS_* constants, exported from the package root.

Version 8.3.0 → 8.4.0, CHANGELOG, unit tests, runtime-e2e driver.

Design decision — transfer_basis stays str | None (read this)

The brief's literal text suggested widening a pydantic Literal on AuditLogEntry.transfer_basis. The field is not a Literal today (it is str | None), and I deliberately kept it str | None rather than converting it to a closed pydantic Literal:

  • AuditLogEntry is a response model. A closed Literal is enforced by pydantic at runtime — a future platform transfer_basis value (the platform comment says values are surfaced verbatim and the set may grow) would raise ValidationError and break search_audit_logs() for any tenant carrying that value. That is exactly the "SDK silently breaks a customer audit read" failure this release is trying to avoid.
  • Instead, type-safety/discoverability is provided by the exported TransferBasis = Literal["adequacy","safeguards","pasal_56b_dpa","consent"] alias (for callers who want to annotate their own variables) and the TRANSFER_BASIS_* string constants. This matches the Go/Java/Rust SDKs, which expose named constants over a permissive string field. TS uses a compile-time-only union (erased at runtime, so it can't reject an unknown value).

Flagging for master/operator sign-off per the No-Silent-Deferrals clause.

§E2E — live platform (current main, includes #2509 + #2513)

python runtime-e2e/decision_context_transfer_basis/test.py against a real agent:

server /decide response: {"verdict":"allow","decision_id":"c6a3d67b-...","stage":"llm",...}
PEP decide -> decision_id=c6a3d67b-48ce-4740-91be-c1d76b434929
SDK list_decisions -> {"decision_id":"c6a3d67b-...","decision":"allow","policy_id":null,"tool_signature":null,"context":{"x_ai_agent":"refund-bot","x_leader_identity":"ops-lead","x_session_id":"sess-buku-42"}}
PASS: list_decisions DecisionSummary.context populated with 3 PEP-forwarded keys
SDK explain_decision -> context={"x_ai_agent":"refund-bot","x_leader_identity":"ops-lead","x_session_id":"sess-buku-42"} context_truncated=None
PASS: explain_decision returned full context (context_truncated=None)
SDK AuditLogEntry round-trip -> {...,"data_residency":"ID","transfer_basis":"pasal_56b_dpa"}
PASS: AuditLogEntry.transfer_basis = 'pasal_56b_dpa' round-trips verbatim
ALL PASS

The driver acts as the PEP via a raw POST /api/v1/decide (not SDK-wrapped per ADR-056), then reads the decision back through the real httpx SDK path.

Tests

pytest1011 passed, 29 skipped, 81% coverage (threshold 75%). ruff check + ruff format --check clean; runtime-e2e no-mocks lint + version-alignment pass. New tests: TestDecisionContextV85 (summary/explanation context, truncated flag, defaults) and TestTransferBasisPasal56b (constants, pasal_56b_dpa round-trip, safeguards backward-compat).

Notes

  • Examples use pip install axonflow (no pinned version) — nothing to bump.
  • DRAFT pending the platform v8.5.0 tag (land order: platform → tag → SDKs).

Epic: getaxonflow/axonflow-enterprise#2508

@saurabhjain1592 saurabhjain1592 force-pushed the buku-e/sdk-v8.5.0 branch 4 times, most recently from af6bcb3 to 0fad2b6 Compare May 30, 2026 00:18
…sfer basis

Targets AxonFlow platform v8.5.0 (epic #2508).

- DecisionSummary + DecisionExplanation gain a context: dict[str, str] | None
  surfacing the sanitized request context a PEP attaches to a Decision Mode call
  (platform #2509). list_decisions() returns the platform-truncated 5-key
  summary; explain_decision() returns the full map plus a
  context_truncated: bool | None flag.
- types.py adds a TransferBasis Literal alias + TRANSFER_BASIS_* constants
  (adequacy, safeguards, pasal_56b_dpa, consent), exported from the package
  root. The AuditLogEntry.transfer_basis field stays str | None (not a closed
  Literal) so existing 'safeguards' code is unaffected and the SDK never rejects
  a value a newer platform may add on an audit read.
- version 8.3.0 -> 8.4.0, CHANGELOG entry, unit tests, and a runtime-e2e driver
  that creates a decision via the PEP path and reads context back through the SDK.

Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com>
@saurabhjain1592 saurabhjain1592 changed the title feat(release): v8.5.0 — decision request context + pasal_56b_dpa transfer basis feat(release): v8.4.0 — decision request context + pasal_56b_dpa transfer basis May 30, 2026
@saurabhjain1592 saurabhjain1592 marked this pull request as ready for review May 30, 2026 11:20
@saurabhjain1592 saurabhjain1592 merged commit c45265a into main May 30, 2026
18 checks passed
@saurabhjain1592 saurabhjain1592 deleted the buku-e/sdk-v8.5.0 branch May 30, 2026 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant